package com.blockchain.console.service.content.achieve;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;

import com.blockchain.common.enums.IsPass;
import com.blockchain.common.enums.NoticeType;
import com.blockchain.console.config.ConsoleConst;
import com.blockchain.console.service.content.NoticeManage;
import com.blockchain.console.service.content.entity.Notice;
import com.blockchain.console.service.content.entity.NoticeRecord;
import com.blockchain.console.service.content.query.NoticeQuery;
import com.blockchain.framework.data.sql.SQLConnectionProvider;
import com.blockchain.framework.service.ServiceFactory;
import com.blockchain.framework.service.ServiceResource;
import com.blockchain.framework.service.exception.ParameterException;
import com.blockchain.framework.service.query.ArrayParser;
import com.blockchain.framework.service.query.ItemParser;
import com.blockchain.framework.service.query.Paging;
import com.blockchain.framework.service.query.PagingResult;
import com.blockchain.util.StringHelper;

public class NoticeManageImpl extends AbstractInformationService implements
		NoticeManage {

	public static class NoticeManageFactory implements
			ServiceFactory<NoticeManage> {

		@Override
		public NoticeManage newInstance(ServiceResource serviceResource) {
			return new NoticeManageImpl(serviceResource);
		}

	}

	public NoticeManageImpl(ServiceResource serviceResource) {
		super(serviceResource);
	}

	protected static final ArrayParser<NoticeRecord> ARRAY_PARSER = new ArrayParser<NoticeRecord>() {

		@Override
		public NoticeRecord[] parse(ResultSet resultSet) throws SQLException {
			
			ArrayList<NoticeRecord> list = null;
			while (resultSet.next()) {
				NoticeRecord record = new NoticeRecord();
				record.id = resultSet.getInt(1);
				record.type = NoticeType.valueOf(resultSet.getString(2));
				record.viewTimes = resultSet.getInt(3);
				record.publishStatus = IsPass.valueOf(resultSet
						.getString(4));
				record.title = resultSet.getString(5);
				record.content = resultSet.getString(6);
				record.publisherId = resultSet.getInt(7);
				record.createTime = resultSet.getTimestamp(8);
				record.updateTime = resultSet.getTimestamp(9);
				record.publisherName = resultSet.getString(10);
				record.titleEn = resultSet.getString(11);
				record.contentEn = resultSet.getString(12);
				record.titleTw = resultSet.getString(13);
				record.contentTw = resultSet.getString(14);
				if (list == null) {
					list = new ArrayList<>();
				}
				list.add(record);
			}
			return list == null || list.size() == 0 ? null : list
					.toArray(new NoticeRecord[0]);
		}
	};
	protected static final ItemParser<NoticeRecord> ITEM_PARSER = new ItemParser<NoticeRecord>() {

		@Override
		public NoticeRecord parse(ResultSet resultSet) throws SQLException {
			NoticeRecord record = null;
			if (resultSet.next()) {
				record = new NoticeRecord();
				record.id = resultSet.getInt(1);
				record.type = NoticeType.valueOf(resultSet.getString(2));
				record.viewTimes = resultSet.getInt(3);
				record.publishStatus = IsPass.valueOf(resultSet
						.getString(4));
				record.title = resultSet.getString(5);
				record.content = resultSet.getString(6);
				record.publisherId = resultSet.getInt(7);
				record.createTime = resultSet.getTimestamp(8);
				record.updateTime = resultSet.getTimestamp(9);
				record.publisherName = resultSet.getString(10);
				record.titleEn = resultSet.getString(11);
				record.contentEn = resultSet.getString(12);
				record.titleTw = resultSet.getString(13);
				record.contentTw = resultSet.getString(14);
			}
			return record;
		}
	};

	protected static final String SELECT_ALL_SQL = "SELECT T5015.F01,T5015.F02,T5015.F03,T5015.F04,T5015.F05,T5015.F06,T5015.F07,T5015.F08,T5015.F09,T7011.F04 AS F10,T5015.F10 AS F11,T5015.F11 AS F12,T5015.F12 AS F13,T5015.F13 AS F14 FROM T5015 INNER JOIN "
			+ ConsoleConst.DB_CONSOLE + ".T7011 ON T5015.F07 = T7011.F01 ";

	@Override
	public PagingResult<NoticeRecord> search(NoticeQuery query, Paging paging)
			throws Throwable {
		ArrayList<Object> parameters = new ArrayList<Object>();
		StringBuilder sql = new StringBuilder(SELECT_ALL_SQL);
		sql.append(" WHERE 1=1 ");
		if (query != null) {
			SQLConnectionProvider connectionProvider = getSQLConnectionProvider();
			NoticeType type = query.getType();
			if (type != null) {
				sql.append(" AND T5015.F02 = ?");
				parameters.add(type);
			}
			IsPass status = query.getPublishStatus();
			if (status != null) {
				sql.append(" AND T5015.F04 = ?");
				parameters.add(status);
			}
			String string = query.getTitle();
			if (!StringHelper.isEmpty(string)) {
				sql.append(" AND T5015.F05 LIKE ?");
				parameters.add(connectionProvider.allMatch(string));
			}
			string = query.getPublisherName();
			if (!StringHelper.isEmpty(string)) {
				sql.append(" AND T7011.F04 LIKE ?");
				parameters.add(connectionProvider.allMatch(string));
			}
			Timestamp timestamp = query.getCreateTimeStart();
			if (timestamp != null) {
				sql.append(" AND DATE(T5015.F08) >= ?");
				parameters.add(timestamp);
			}
			timestamp = query.getCreateTimeEnd();
			if (timestamp != null) {
				sql.append(" AND DATE(T5015.F08) <= ?");
				parameters.add(timestamp);
			}
			timestamp = query.getUpdateTimeStart();
			if (timestamp != null) {
				sql.append(" AND DATE(T5015.F09) >= ?");
				parameters.add(timestamp);
			}
			timestamp = query.getUpdateTimeEnd();
			if (timestamp != null) {
				sql.append(" AND DATE(T5015.F09) <= ?");
				parameters.add(timestamp);
			}
		}
		sql.append(" ORDER BY T5015.F09 DESC");
		return selectPaging(getConnection(), ARRAY_PARSER, paging,
				sql.toString(), parameters);
	}

	@Override
	public NoticeRecord get(int id) throws Throwable {
		if (id <= 0) {
			return null;
		}
		return select(getConnection(), ITEM_PARSER, SELECT_ALL_SQL
				+ " WHERE T5015.F01 = ?", id);
	}

	@Override
	public void delete(int... ids) throws Throwable {
		if (ids == null || ids.length == 0) {
			return;
		}
		serviceResource.openTransactions();
		try (Connection connection = getConnection();
				PreparedStatement pstmt = connection
						.prepareStatement("DELETE FROM T5015 WHERE F01 = ?");) {
			for (int id : ids) {
				if (id <= 0) {
					continue;
				}
				pstmt.setInt(1, id);
				pstmt.addBatch();
			}
			pstmt.executeBatch();
		}
	}

	@Override
	public int add(Notice notice) throws Throwable {
		if (notice == null) {
			throw new ParameterException("没有指定公告信息");
		}
		String title;
		String titleEn = "";
		String titleTw = "";
		IsPass publishStatus;
		NoticeType type;
		String content;
		String contentEn = "";
		String contentTw = "";
		Timestamp createTime;
		{
			title = notice.getTitle();
			if (StringHelper.isEmpty(title)) {
				throw new ParameterException("公告标题不能为空");
			}
			content = notice.getContent();
			if (StringHelper.isEmpty(content)) {
				throw new ParameterException("公告内容不能为空");
			}
			if(isMultiLang()) {
				titleEn = notice.getTitleEn();
				if (StringHelper.isEmpty(titleEn)) {
					throw new ParameterException("公告标题(英文)不能为空");
				}
				contentEn = notice.getContentEn();
				if (StringHelper.isEmpty(contentEn)) {
					throw new ParameterException("公告内容(英文)不能为空");
				}
				titleTw = notice.getTitleTw();
				if (StringHelper.isEmpty(titleTw)) {
					throw new ParameterException("公告标题(繁体)不能为空");
				}
				contentTw = notice.getContentTw();
				if (StringHelper.isEmpty(contentTw)) {
					throw new ParameterException("公告内容(繁体)不能为空");
				}
			}
			type = notice.getType();
			if (type == null) {
				throw new ParameterException("公告类型不能为空");
			}
			publishStatus = notice.getPublishStatus();
			if (publishStatus == null) {
				throw new ParameterException("公告发布状态不能为空");
			}
			createTime = notice.getCreateTime();
			if (createTime == null) {
				throw new ParameterException("发布时间不能为空");
			}
		}
		return insert(
				getConnection(),
				"INSERT INTO T5015 SET F02 = ?, F04 = ?, F05 = ?, F06 = ?, F10 = ?, "
				+ "F11 = ?, F12 = ?, F13 = ?, F07 = ?, F08 = ?",
				type, publishStatus, title, content, titleEn, contentEn, titleTw, contentTw, serviceResource
						.getSession().getAccountId(),createTime);
	}

	@Override
	public void update(int id, Notice notice) throws Throwable {
		if (id <= 0 || notice == null) {
			return;
		}
		String title;
		String titleEn = "";
		String titleTw = "";
		IsPass publishStatus;
		NoticeType type;
		String content;
		String contentEn = "";
		String contentTw = "";
		Timestamp createTime;
		{
			title = notice.getTitle();
			if (StringHelper.isEmpty(title)) {
				throw new ParameterException("公告标题不能为空");
			}
			content = notice.getContent();
			if (StringHelper.isEmpty(content)) {
				throw new ParameterException("公告内容不能为空");
			}
			if(isMultiLang()) {
				titleEn = notice.getTitleEn();
				if (StringHelper.isEmpty(titleEn)) {
					throw new ParameterException("公告标题（英文）不能为空");
				}
				contentEn = notice.getContentEn();
				if (StringHelper.isEmpty(contentEn)) {
					throw new ParameterException("公告内容（英文）不能为空");
				}
				titleTw = notice.getTitleTw();
				if (StringHelper.isEmpty(titleTw)) {
					throw new ParameterException("公告标题（繁体）不能为空");
				}
				contentTw = notice.getContentTw();
				if (StringHelper.isEmpty(contentTw)) {
					throw new ParameterException("公告内容（繁体）不能为空");
				}
			}
			type = notice.getType();
			if (type == null) {
				throw new ParameterException("公告类型不能为空");
			}
			publishStatus = notice.getPublishStatus();
			if (publishStatus == null) {
				throw new ParameterException("公告发布状态不能为空");
			}
			createTime = notice.getCreateTime();
			if (createTime == null) {
				throw new ParameterException("发布时间不能为空");
			}
		}
		execute(getConnection(),
				"UPDATE T5015 SET F02 = ?, F04 = ?, F05 = ?, F06 = ?,F10 = ?, F11 = ?,F12 = ?, F13 = ?,"
				+ "F08 = ?,F09=? WHERE F01 = ?",type, publishStatus, title, content, titleEn, 
				contentEn, titleTw, contentTw,createTime,new Timestamp(System.currentTimeMillis()) ,id);
	}

	@Override
	public void setPublishStatus(IsPass publishStatus, int... ids)
			throws Throwable {
		if (publishStatus == null || ids == null || ids.length == 0) {
			return;
		}
		serviceResource.openTransactions();
		try (Connection connection = getConnection();
				PreparedStatement pstmt = connection
						.prepareStatement("UPDATE T5015 SET F04 = ? WHERE F01 = ?");) {
			for (int id : ids) {
				if (id <= 0) {
					continue;
				}
				pstmt.setString(1, publishStatus.name());
				pstmt.setInt(2, id);
				pstmt.addBatch();
			}
			pstmt.executeBatch();
		}
	}

	public boolean isMultiLang() {
		return this.serviceResource.getSystemDefine().isMulitLanguage();
	}
}
